package com.bwie.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.poi.StringUtils;
import com.bwie.pojo.TbMenu;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.KaptchaUtils;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.Result;
import com.bwie.vo.LoginVo;
import com.bwie.vo.PageUserVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author 39304
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-05-21 15:54:49
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{
    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    HttpServletResponse response;

    @Autowired
    FastFileStorageClient fastFileStorageClient;

    @Autowired
    HttpServletRequest request;

    @Override
    public Result login(LoginVo loginVo) {
        TbUser tbUser = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, loginVo.getUserName())
        );
        if (tbUser == null){
            return Result.error().setMsg("用户不存在");
        }

        String hash = DigestUtil.md5Hex(loginVo.getUserPass());
        System.out.println("加密密码：" + hash);
        if (!hash.equals(tbUser.getUserPass())){
            return Result.error().setMsg("密码错误");
        }

        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", tbUser.getUserId())
                .claim("userName", tbUser.getUserName())
                .claim("userReal", tbUser.getRealName())
                .compact();

        String tokenKey = "token-" + tbUser.getUserId();

        redisTemplate.opsForValue().set(tokenKey,token,60, TimeUnit.MINUTES);

        tbUser.setUserPass(null);
        tbUser.setToken(token);

        return Result.ok().setData(tbUser);
    }

    @Override
    public void code() {
        String code = RandomUtil.randomNumbers(4);
        redisTemplate.opsForValue().set(code,code,15,TimeUnit.MINUTES);

        KaptchaUtils.generateCaptcha(response,code);
    }

    @Override
    public Result sendCode(String mobile, String code) {
        Boolean hasKey = redisTemplate.hasKey(code);
        if (!hasKey){
            return Result.error().setMsg("图片验证码错误");
        }

        String sendKey = "send-" + mobile;
        Boolean hasKey1 = redisTemplate.hasKey(sendKey);
        if (hasKey1){
            return Result.error().setMsg("验证码发送频繁，请60秒后重试");
        }

        TbUser tbUser = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, mobile)
        );
        if (tbUser == null){
            return Result.error().setMsg("手机号不存在");
        }

        String mobileCode = RandomUtil.randomNumbers(4);
        redisTemplate.opsForValue().set(mobile,mobileCode,15,TimeUnit.MINUTES);

        MobileMessageUtil.sendMobileMessage(mobile,mobileCode);

        redisTemplate.opsForValue().set(sendKey,mobileCode,1,TimeUnit.MINUTES);

        return Result.ok();
    }

    @Override
    public Result loginMobile(LoginVo loginVo) {
        String code = redisTemplate.opsForValue().get(loginVo.getMobile());
        if (code == null){
            return Result.error().setMsg("验证码已过期");
        }
        if (!code.equals(loginVo.getCode())){
            return Result.error().setMsg("验证码错误");
        }

        TbUser tbUser = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, loginVo.getMobile())
        );
        if (tbUser == null){
            return Result.error().setMsg("手机号不存在");
        }

        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", tbUser.getUserId())
                .claim("userName", tbUser.getUserName())
                .claim("realName", tbUser.getRealName())
                .compact();

        String tokenKey = "token-" + tbUser.getUserId();

        redisTemplate.opsForValue().set(tokenKey,token,60,TimeUnit.MINUTES);


        tbUser.setUserPass(null);
        tbUser.setToken(token);


        return Result.ok().setData(tbUser);
    }

    @Override
    public Result getUserList(PageUserVo pageUserVo) {
        Page<TbUser> page = new Page<>(pageUserVo.getPageNum(), pageUserVo.getPageSize());

        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();

        if (StringUtils.isNotEmpty(pageUserVo.getKeyWord())){
            wrapper.lambda().or().like(TbUser::getUserName,pageUserVo.getKeyWord());
            wrapper.lambda().or().like(TbUser::getRealName,pageUserVo.getKeyWord());
            wrapper.lambda().or().like(TbUser::getUserMobile,pageUserVo.getKeyWord());
            wrapper.lambda().or().like(TbUser::getUserEmail,pageUserVo.getKeyWord());
        }

        if (pageUserVo.getGander() != null){
            wrapper.lambda().eq(TbUser::getGender,pageUserVo.getGander());
        }

        if (pageUserVo.getStartTime() != null){
            wrapper.lambda().ge(TbUser::getCreateTime,pageUserVo.getStartTime());
        }

        if (pageUserVo.getEndTime() != null){
            wrapper.lambda().le(TbUser::getCreateTime,pageUserVo.getEndTime());
        }

        Page<TbUser> tbUserPage = tbUserMapper.selectPage(page, wrapper);

        return Result.ok().setData(tbUserPage);
    }

    @Override
    public Result uploadFile(MultipartFile file) {
        try {
            String extName = FileNameUtil.extName(file.getOriginalFilename());
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
            String url = "http://192.168.239.131:8888/" + storePath.getFullPath();

            return Result.ok().setData(url);
        } catch (IOException e) {
//            throw new RuntimeException(e);
            e.printStackTrace();
            return Result.error().setMsg("上传失败");
        }
    }

    @Override
    public Result updateUser(TbUser tbUser) {
        TbUser user = tbUserMapper.selectById(tbUser.getUserId());
        if (user == null){
            return Result.error().setMsg("用户不存在");
        }

        tbUserMapper.updateById(tbUser);

        return Result.ok();
    }

    @Override
    public List getMenuById(Integer userId) {
        List<TbMenu> menuList = tbUserMapper.getMenuById(userId);

        List<Tree<String>> treeList = TreeUtil.build(menuList, "0", (menu, tree) -> {
            tree.setId(menu.getMenuId() + "");
            tree.setName(menu.getMenuName());
            tree.setParentId(menu.getMenuPid() + "");
            tree.putExtra("path",menu.getMenuPath());
        });

        return treeList;
    }

    @Override
    public Result deleteById(Integer userId) {
        TbUser tbUser = tbUserMapper.selectById(userId);
        if (tbUser == null){
            return Result.error().setMsg("用户不存在");
        }

        tbUserMapper.deleteById(userId);

        return Result.ok();
    }

    @Override
    public Result deleteByIdAll(List<TbUser> userList) {
        if (userList == null || userList.size() == 0){
            return Result.error().setMsg("请选择要删除的用户");
        }

        for (TbUser tbUser : userList) {
            tbUserMapper.deleteById(tbUser.getUserId());
        }

        return Result.ok();
    }

    @Override
    public Result checkUser(TbUser tbUser) {
        if (tbUser.getUserStatus() == 2){
            if (StringUtils.isEmpty(tbUser.getReason())){
                return Result.error().setMsg("请输入审核不通过原因");
            }
        }

        TbUser user = tbUserMapper.selectById(tbUser.getUserId());
        if (user == null){
            return Result.error().setMsg("用户不存在");
        }

        user.setUserStatus(tbUser.getUserStatus());
        user.setReason(tbUser.getReason());
        tbUserMapper.updateById(user);

        return Result.ok();
    }
}




